#ifndef __SLOTHTTPD_NGX_PARSER_PARSER_H__
#define __SLOTHTTPD_NGX_PARSER_PARSER_H__


#ifdef __cplusplus
#  include <cstddef>
#  include <cstdint>
#else
#  include <stddef.h>
#  include <stdint.h>
#endif
#include <slothttpd/ngx_parser/ngx_string.h>


#define NGX_HTTP_PARSE_HEADER_DONE         1

#define NGX_HTTP_PARSE_INVALID_METHOD      10
#define NGX_HTTP_PARSE_INVALID_REQUEST     11
#define NGX_HTTP_PARSE_INVALID_09_METHOD   12

#define NGX_HTTP_UNKNOWN                   0x0001
#define NGX_HTTP_GET                       0x0002
#define NGX_HTTP_HEAD                      0x0004
#define NGX_HTTP_POST                      0x0008
#define NGX_HTTP_PUT                       0x0010
#define NGX_HTTP_DELETE                    0x0020
#define NGX_HTTP_MKCOL                     0x0040
#define NGX_HTTP_COPY                      0x0080
#define NGX_HTTP_MOVE                      0x0100
#define NGX_HTTP_OPTIONS                   0x0200
#define NGX_HTTP_PROPFIND                  0x0400
#define NGX_HTTP_PROPPATCH                 0x0800
#define NGX_HTTP_LOCK                      0x1000
#define NGX_HTTP_UNLOCK                    0x2000
#define NGX_HTTP_PATCH                     0x4000
#define NGX_HTTP_TRACE                     0x8000

#define NGX_HTTP_PARSE_INVALID_HEADER      13


#define  NGX_OK          0
#define  NGX_ERROR      -1
#define  NGX_AGAIN      -2
#define  NGX_BUSY       -3
#define  NGX_DONE       -4
#define  NGX_DECLINED   -5
#define  NGX_ABORT      -6

/* must be 2^n */
#define NGX_HTTP_LC_HEADER_LEN             32



#define LF     (u_char) '\n'
#define CR     (u_char) '\r'
#define CRLF   "\x0d\x0a"


struct ngx_buf_s {
    u_char          *pos;
    u_char          *last;
};

typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;


struct ngx_http_request_s {
    /* URI with "/." and on Win32 with "//" */
    unsigned                          complex_uri:1;

    /* URI with "%" */
    unsigned                          quoted_uri:1;

    /* URI with "+" */
    unsigned                          plus_in_uri:1;

    /* URI with " " */
    unsigned                          space_in_uri:1;

    //unsigned                          invalid_header:1;

    ngx_uint_t                        method;
    ngx_uint_t                        http_version;

    //ngx_str_t                         request_line;
    //ngx_str_t                         uri;
    //ngx_str_t                         args;

    //ngx_str_t                         method_name;
    ngx_str_t                         http_protocol;


    /* used to parse HTTP headers */
    ngx_uint_t                        state;

    /*
     * a memory that can be reused after parsing a request line
     * via ngx_http_ephemeral_t
     */

    u_char                           *uri_start;
    u_char                           *uri_end;
    u_char                           *uri_ext;
    u_char                           *args_start;
    u_char                           *request_start;
    u_char                           *request_end;
    u_char                           *method_end;
    u_char                           *schema_start;
    u_char                           *schema_end;
    u_char                           *host_start;
    u_char                           *host_end;
    u_char                           *port_start;
    u_char                           *port_end;

    unsigned                          http_minor:16;
    unsigned                          http_major:16;
};


typedef struct {
    ngx_uint_t           http_version;
    ngx_uint_t           code;
    ngx_uint_t           count;
    u_char              *start;
    u_char              *end;
} ngx_http_status_t;


typedef struct ngx_http_request_s       ngx_http_request_t;
typedef struct ngx_buf_s                ngx_buf_t;


#ifdef __cplusplus
extern "C" {
#endif


    ngx_int_t
    ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);


#ifdef __cplusplus
}
#endif

#endif
